package com.neusoft.hifly.dictionary.area.api;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;

import com.neusoft.hifly.commons.exception.SystemErrorException;
import com.neusoft.hifly.commons.lang.LongUtil;
import com.neusoft.hifly.core.basic.domain.ZTreeNode;
import com.neusoft.hifly.core.pojo.ApiCode;
import com.neusoft.hifly.core.pojo.ApiResponse;
import com.neusoft.hifly.core.utils.GlobalConstants;
import com.neusoft.hifly.dictionary.area.entity.AreaObj;
import com.neusoft.hifly.dictionary.area.entity.CityObj;
import com.neusoft.hifly.dictionary.area.entity.ProvObj;
import com.neusoft.hifly.dictionary.area.service.IAreaService;
import com.neusoft.hifly.dictionary.area.service.ICityService;
import com.neusoft.hifly.dictionary.area.service.IProvService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * Title: 数据字典服务
 * <p>
 * Description: 区信息 接口
 * <p>
 * Copyright: 2019
 * <p>
 * Company: 东软汉枫
 *
 * @author lh_neu
 * @version 1.0.0
 */
@CrossOrigin
@RestController
@RequestMapping("/api/v1/area")
@Api(value = "area-api", description = "区信息接口")
public class AreaApi {
	@Autowired(required = false)
	private IProvService provService;
	@Autowired(required = false)
	private ICityService cityService;
	@Autowired(required = false)
	private IAreaService areaService;

	/**
	 * 查询所有数据
	 *
	 * @return 集合
	 */
	@ApiOperation("查询区信息集合")
	@GetMapping(value = "/list")
	public ApiResponse<?> findAll() {
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！", areaService.findAll());
	}

	/**
	 * 将省市区封装后一同返回
	 *
	 * @return 集合
	 */
	@ApiOperation("将省市区封装后一同返回")
	@GetMapping(value = "/select")
	public ApiResponse<?> findBySelect() {
		final List<ZTreeNode> nodeList = new ArrayList<ZTreeNode>(0);
		ZTreeNode node = null;

		// 获取省
		final List<ProvObj> provinceObjs = provService.findAll();
		if (provinceObjs != null && !provinceObjs.isEmpty()) {
			for (final ProvObj proObj : provinceObjs) {
				node = new ZTreeNode("prov", proObj.getName()).logicId(proObj.getLogicId()).name(proObj.getName());
				nodeList.add(node);

				// 获取市
				final List<CityObj> citys = cityService.findByProvLogicId(proObj.getLogicId());
				if (citys != null && !citys.isEmpty()) {
					for (final CityObj cityObj : citys) {
						node = new ZTreeNode("city", cityObj.getName()).logicId(cityObj.getLogicId())
								.name(cityObj.getName()).fatherLogicId(cityObj.getProvinceLogicId());
						nodeList.add(node);

						// 获取区
						final List<AreaObj> areas = areaService.findByCityLogicId(cityObj.getLogicId());
						if (areas != null && !areas.isEmpty()) {
							for (final AreaObj areaObj : areas) {
								node = new ZTreeNode("area", areaObj.getName()).logicId(areaObj.getLogicId())
										.name(areaObj.getName()).fatherLogicId(areaObj.getCityLogicId());
								nodeList.add(node);
							}
						}
					}
				}
			}
		}

		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！", nodeList);
	}

	/**
	 * 通过城市ID查询地区列表
	 *
	 * @param cityLogicId
	 *            城市逻辑ID
	 * @return 集合
	 */
	@ApiOperation("通过城市ID查询地区列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "cityLogicId", value = "城市逻辑ID", dataType = "long", paramType = "path", required = true) })
	@GetMapping(value = "/city/{cityLogicId}")
	public ApiResponse<?> findByProvLogicId(@PathVariable("cityLogicId") final long cityLogicId) {
		if (LongUtil.isEmpty(cityLogicId)) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！", areaService.findByCityLogicId(cityLogicId));
	}

	/**
	 * 分页查询
	 *
	 * @param HttpServletRequest
	 *            request
	 * @return 集合
	 */
	@ApiOperation("分页查询")
	@ApiImplicitParams({ @ApiImplicitParam(name = "offset", value = "开始索引", dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "limit", value = "每页纪录数", dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "cityLogicId", value = "市逻辑ID", dataType = "long", paramType = "query", required = true),
			@ApiImplicitParam(name = "areaName", value = "区信息", dataType = "String", paramType = "query") })
	@GetMapping(value = "/search")
	public ApiResponse<?> search(final HttpServletRequest request) {
		final String offsetStr = StringUtils.trimToEmpty(request.getParameter("offset"));
		final String limitStr = StringUtils.trimToEmpty(request.getParameter("limit"));
		int offset = GlobalConstants.PAGE_OFFSET;
		int limit = GlobalConstants.PAGE_LIMIT;
		if (StringUtils.isNotEmpty(offsetStr) && StringUtils.isNumeric(offsetStr)) {
			offset = Integer.parseInt(offsetStr);
		}
		if (StringUtils.isNotEmpty(limitStr) && StringUtils.isNumeric(limitStr)) {
			limit = Integer.parseInt(limitStr);
		}

		// 参数
		final Map<String, Object> params = new HashMap<String, Object>(0);
		// 添加搜索
		searchWhere(request, params);
		final IPage<AreaObj> page = areaService.search(offset, limit, params);

		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！", page);
	}

	/**
	 * 通过逻辑ID获取区信息
	 *
	 * @param logicId
	 *            区信息逻辑ID
	 * @return 区信息信息
	 */
	@ApiOperation("通过逻辑ID获取区信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "logicId", value = "区信息逻辑ID", dataType = "long", paramType = "path", required = true) })
	@GetMapping(value = "/{logicId}")
	public ApiResponse<?> getByLogicId(@PathVariable("logicId") final long logicId) {
		if (LongUtil.isEmpty(logicId)) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}
		final AreaObj obj = areaService.getByLogicId(logicId);
		if (obj == null) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "数据不存在！");
		}
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！", obj);
	}

	/**
	 * 通过逻辑ID删除区信息
	 *
	 * @param logicId
	 *            区信息ID，多id使用英文逗号分隔
	 * @return 成功信息
	 */
	@ApiOperation("通过逻辑ID删除区信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "logicId", value = "区信息ID，多id使用英文逗号分隔", dataType = "string", paramType = "path", required = true) })
	@DeleteMapping(value = "/{logicId}")
	public ApiResponse<?> delete(@PathVariable("logicId") final String logicId) {
		if (StringUtils.isEmpty(logicId)) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}
		areaService.deleteByBatch(logicId);
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！");
	}

	/**
	 * 初始化编辑
	 *
	 * @param logicId
	 *            区信息逻辑ID
	 * @return 区信息信息
	 */
	@ApiOperation("初始化编辑")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "logicId", value = "区信息逻辑ID", dataType = "long", paramType = "path", required = true) })
	@GetMapping(value = "/initEdit/{logicId}")
	public ApiResponse<?> initEdit(@PathVariable("logicId") final long logicId) {
		if (LongUtil.isEmpty(logicId)) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}
		final AreaObj obj = areaService.getByLogicId(logicId);
		if (obj == null) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "数据不存在！");
		}
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！", obj);
	}

	/**
	 * 新增区信息
	 *
	 * @param obj
	 *            区信息信息
	 * @return 区信息信息
	 */
	@ApiOperation("新增区信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "obj", value = "区信息信息", dataType = "AreaObj", required = true) })
	@PostMapping(value = "")
	public ApiResponse<?> save(@RequestBody final AreaObj obj) {
		if (obj == null) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}
		try {
			areaService.saveOrUpdate(obj);
		} catch (final SystemErrorException e) {
			return new ApiResponse<>(e);
		}
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！");
	}

	/**
	 * 更新区信息
	 *
	 * @param obj
	 *            区信息信息
	 * @return 区信息信息
	 */
	@ApiOperation("更新区信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "obj", value = "区信息信息", dataType = "AreaObj", required = true) })
	@PutMapping(value = "")
	public ApiResponse<?> update(@RequestBody final AreaObj obj) {
		if (obj == null) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "参数错误!");
		}
		final AreaObj oldObj = areaService.getByLogicId(obj.getLogicId());
		if (oldObj == null) {
			return new ApiResponse<>(ApiCode.ERROR.getCode(), "区信息不存在！");
		}
		try {
			areaService.saveOrUpdate(obj);
		} catch (final SystemErrorException e) {
			return new ApiResponse<>(e);
		}
		return new ApiResponse<>(ApiCode.SUCCESS.getCode(), "成功！");
	}

	/**
	 * 搜索条件
	 *
	 * @param request
	 *            HttpServletRequest
	 * @param property
	 *            参数
	 */
	private void searchWhere(final HttpServletRequest request, final Map<String, Object> property) {
		boolean isLike = false;
		final String cityLogicId = StringUtils.trimToEmpty(request.getParameter("cityLogicId"));
		if (StringUtils.isNotEmpty(cityLogicId)) {
			property.put("cityLogicId", cityLogicId);
		}
		final String name = StringUtils.trimToEmpty(request.getParameter("name"));
		if (StringUtils.isNotEmpty(name)) {
			property.put("name", name);
			isLike = true;
		}
		property.put("isLike", isLike);
	}
}